# Simple PHPUnit Example

A simple code example of unit tests with PHP codebase.

Contains test for both class methods and loose functions.


## How to test

```bash
cd /path/to/this/repo
./vendor/bin/phpunit tests
```

As simple as that!


## Tutorial


### Step 1: Creating your code

Create a directory, let's say `myproject`. Inside it create another directory for PHP source files. e.g. `src`. Put your classes and code in. This should be how you normally have your code. There is no restriction on anything here. Just put everything like normal.

For example, let's create a class called `AdderClass`:

```php
<?php
class AdderClass {
	function __construct($num1, $num2) {
		return $this->add($num1, $num2);
	}
	function add($num1, $num2) {
		return $num1 + $num2;
	}
}
```

If you're unsure, use the `src` folder from this repo.


### Step 2: Setup PHPUnit

On terminal, `cd` to the `myproject` directory. Now run `composer require --dev phpunit/phpunit ^9` to install PHPUnit. This should create a `composer.json` file with this text:

```json
{
    "require-dev": {
        "phpunit/phpunit": "^9"
    }
}
```

Now add the `src` folder to this file, so that it can be discovered by Composer, like below:

```json
{
    "autoload": {
        "classmap": [
            "src/"
        ]
    },
    "require-dev": {
        "phpunit/phpunit": "^9"
    }
}
```


### Step 3: Prepare test files

Prepare test files like you see on `tests` folder of this repo. Be sure to append `...Test.php` after each filename so that it is seen by PHPUnit as a test file. For example, `SomeClassNameTest.php`. Also make sure to keep every method inside a test file as `public`. 

You can test with an example input to test if an expected output is given:

`tests/AdderClassTest.php`
```php
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class AdderClassTest extends TestCase
{
    public function testSomethingYouWantToTest(): void
    {
        $this->assertEquals(
            4,
            AdderClass::add(2, 2)
        );
    }

}
```

This creates an instance of `AdderClass` and executes `add` method of that class and tests if the result is `4`. If not, PHPUnit will let us know that the method is not working. Otherwise it will pass.

You can also test for exceptions:

`src/AdderClass.class.php`
```php
<?php
class AdderClass {
    // ...
	function add($num1, $num2) {
		if ( ( strval($num1) !== strval(intval($num1)) ) || ( strval($num2) !== strval(intval($num2)) ) ) {
			throw new InvalidArgumentException('Input is not an integer');
		}
		return $num1 + $num2;
	}
}
```

The test would be:

```php
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
// ...
final class AdderClassTest extends TestCase
{
    // ...
    public function testAddingNonInteger(): void
    {
        $this->expectException(InvalidArgumentException::class);
        AdderClass::add('abc', 2);
    }

}
```

You can also test functions outside of a class like this:

`tests/CommonTest.php`
```php
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

// Include the file where the functions are.
// We would have to include the file manually since composer won't be
// able to import it because it's not a class.
require_once(dirname(__DIR__) . '/src/common.php');

final class CommonTest extends TestCase
{
    public function testUppercase(): void
    {
    	// Testing a custom function named "uppercase"...
        $this->assertEquals(
            'SOME TEXT SAMPLE',
            uppercase('Some text sample')
        );
    }

}
```

If you're unsure how to write these files, use the `tests` folder from this repo for a start.


### Step 4: Run tests

Now run `composer dump-autoload -o` so that Composer can auto-include class files when `use \SomeNamespace\SomeClass` etc. is used.

Now to run the tests, run `./vendor/bin/phpunit tests`. Here `tests` is the tests folder. It should output something like this:

```
$ ./vendor/bin/phpunit tests
PHPUnit 9.3.7 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 00:00.024, Memory: 4.00 MB

OK (2 tests, 2 assertions)
```

Ref: [Getting Started with Version 9 of PHPUnit &#x2013; The PHP Testing Framework](https://phpunit.de/getting-started/phpunit-9.html)
